/*
	           MICRO-MENU

	     (C) Dean Camera, 2007
	    www.fourwalledcubicle.com
	dean_camera@fourwalledcubicle.com
	
	    Royalty-free for all uses.
	                                  */

#ifndef MENU_H
#define MENU_H

#include <avr/pgmspace.h>
#include "../encoder/encoder.h"

// Typedefs:
typedef void (*FuncPtr)(void);
typedef void (*WriteFuncPtr)(const char*);

typedef struct PROGMEM{
	void       *Next;
	void       *Previous;
	void       *Parent;
	void       *Sibling;
	FuncPtr     SelectFunc;
	FuncPtr     EnterFunc;	
	unsigned short 	   *ADC_numb;
	const char  Text_units[6];
	const char  Text[];
} Menu_Item ;

struct str_menu_data {
unsigned short membrane_sens;
unsigned short amp_ch1;
unsigned short amp_ch2;
unsigned short amp_ch3;
unsigned short amp_ch4;
unsigned short mod_lazer1;
unsigned short mod_lazer2;
unsigned short volume;
unsigned short backlight;
unsigned short current_lazer1;
unsigned short current_lazer2;
unsigned short power_lazer1;
unsigned short power_lazer2;
unsigned char manual_ch_number;
unsigned short modulation;
};

// Externs:
extern WriteFuncPtr*    WriteFunc;
extern Menu_Item        Null_Menu;
extern Menu_Item*       CurrMenuItem;

// Defines and Macros:
#define NULL_ENTRY Null_Menu
#define NULL_FUNC  (void*)0
#define NULL_TEXT  0x00


#define PREVIOUS   ((Menu_Item*)pgm_read_word(&CurrMenuItem->Previous))
#define NEXT       ((Menu_Item*)pgm_read_word(&CurrMenuItem->Next))
#define PARENT     ((Menu_Item*)pgm_read_word(&CurrMenuItem->Parent))
#define SIBLING    ((Menu_Item*)pgm_read_word(&CurrMenuItem->Sibling))
#define ENTERFUNC  ((FuncPtr*)pgm_read_word(&CurrMenuItem->EnterFunc))
#define SELECTFUNC ((FuncPtr*)pgm_read_word(&CurrMenuItem->SelectFunc))
#define SHOW_ADC_NUMB ((unsigned short*)pgm_read_word(&CurrMenuItem->ADC_numb))

#define MAKE_MENU(Name, Next, Previous, Parent, Sibling, SelectFunc, EnterFunc,	ADC_numb,Text_units, ...) \
    extern Menu_Item Next;     \
	extern Menu_Item Previous; \
	extern Menu_Item Parent;   \
	extern Menu_Item Sibling;  \
	Menu_Item Name = {(void*)&Next, (void*)&Previous, (void*)&Parent, (void*)&Sibling, (FuncPtr)SelectFunc, (FuncPtr)EnterFunc,(unsigned short*)&ADC_numb,{Text_units},{__VA_ARGS__}}

#define SET_MENU_WRITE_FUNC(x) \
	WriteFunc = (WriteFuncPtr*)x;

#define SET_MENU(x) \
	MenuChange((Menu_Item*)x);
	
#define GO_MENU_FUNC(x)  \
	MenuFunc((FuncPtr*)x)
	
#define EXTERN_MENU(Name) \
    extern Menu_Item Name;

#define MENU_MODE_AUTOMATION &m_s4i1
#define MENU_MODE_MANUAL &m_s4i2
#define MENU_AMP_CHANNEL1 &m_s10i1
#define MENU_AMP_CHANNEL2 &m_s10i2 
#define MENU_AMP_CHANNEL3 &m_s10i3 
#define MENU_AMP_CHANNEL4 &m_s10i4 

#define MENU_CURRENT_LAZER1 &m_s11i1 
#define MENU_CURRENT_LAZER2 &m_s11i2
 
#define MENU_POWER_LAZER1 &m_s12i1 
#define MENU_POWER_LAZER2 &m_s12i2 
#define MENU_SET_POWER_LAZER1 &m_s9i1
#define MENU_SET_POWER_LAZER2 &m_s9i2

#define MENU_SET_MOD_LAZER1 &m_s14i1
#define MENU_SET_MOD_LAZER2 &m_s14i2

#define MENU_SET_VOLUME &m_s3i4
#define MENU_SET_BACKLIGHT &m_s3i5
#define MENU_SET_MODULATION &m_s3i6

#define ENTER_IS_PRESSED (button_number == 2)

// Prototypes:
void MenuChange(Menu_Item* NewMenu);
void MenuFunc(FuncPtr* Function);
void MenuInit (void);
void show_menu_on_LCD(void);
void show_ADC_on_LCD (void);

void menu_set_control_status (void);
void menu_show_control_status (void);

void menu_set_amp_ch1 (void);
void menu_set_amp_ch2 (void);
void menu_set_amp_ch3 (void);
void menu_set_amp_ch4 (void);

void menu_set_mod_lazer1 (void);
void menu_set_mod_lazer2 (void);

void menu_set_volume (void);
void menu_set_backlight (void);

void menu_set_power_lazer1 (void);
void menu_set_power_lazer2 (void);

void menu_set_modulation (void);


void _menu_set_control_status (void);

void _menu_test_optic (void);
void _menu_test_membrane (void);
void _menu_test_lazer (void);
void _menu_test_diode (void);

void _menu_set_amp_ch1 (void);
void _menu_set_amp_ch2 (void);
void _menu_set_amp_ch3 (void);
void _menu_set_amp_ch4 (void);

void _menu_set_mod_lazer1 (void);
void _menu_set_mod_lazer2 (void);

void _menu_set_volume (void);
void _menu_set_backlight (void);

void _menu_set_manual_ch1 (void);
void _menu_set_manual_ch2 (void);
void _menu_set_manual_ch3 (void);
void _menu_set_manual_ch4 (void);

void _menu_set_power_lazer1 (void);
void _menu_set_power_lazer2 (void);

void _menu_set_modulation (void);

void menu_handler (unsigned  ,unsigned  , unsigned ,unsigned ,unsigned ,unsigned ,encoder *);
void select_menu_function (void);

unsigned char* enter_number_frm_keyboard (unsigned char ,unsigned char );

unsigned char* short_to_mass (unsigned short *,unsigned,unsigned,unsigned,unsigned);
unsigned short mass_to_short (unsigned char *,unsigned,unsigned,unsigned,unsigned);

#endif
